<?php
/**
 * Created by PhpStorm.
 * User: TS
 * Date: 2017/4/4
 * Time: 20:27
 */
namespace core\http;

class Response
{

    protected static $instance;

    protected $response;

    protected $isEnd = false;

    public function __construct(\swoole\http\response $response)
    {
        $this->response = $response;
    }

    /**
     * @param \swoole\http\response|null $response
     * @return static
     */
    public static function getInstance(\swoole\http\response $response = null)
    {
        if (!isset(self::$instance)) {
            self::$instance = new static($response);
        }
        return self::$instance;
    }

    /**
     * 设置HTTP响应的Header信息
     * header设置必须在end方法之前
     * $key必须完全符合Http的约定，每个单词首字母大写，不得包含中文，下划线或者其他特殊字符
     * $value必须填写
     * @param $key
     * @param $value
     * @return mixed
     * $responser->header('Content-Type', 'image/jpeg');
     */
    public function header($key, $value)
    {
        return $this->response->header($key, $value);
    }

    /**
     * 设置HTTP响应的cookie信息。此方法参数与PHP的setcookie完全一致
     * cookie设置必须在end方法之前
     * @param $key
     * @param string $value
     * @param $expire
     * @param string $path
     * @param string $domain
     * @param bool $secure
     * @param bool $httpOnly
     * @return mixed
     */
    public function cookie($key, $value = '', $expire = 0, $path = '/', $domain = '', $secure = false, $httpOnly = false)
    {
        return $this->response->cookie($key, $value, $expire, $path, $domain, $secure, $httpOnly);
    }

    /**
     * $http_status_code必须为合法的HttpCode，如200， 502， 301, 404等，否则会报错
     * 必须在$response->end之前执行status
     * @param int $httpStatusCode
     */
    public function status($httpStatusCode = 200)
    {
        $this->response->status($httpStatusCode);
    }

    /**
     * 启用Http GZIP压缩。压缩可以减小HTML内容的尺寸，
     * 有效节省网络带宽，提高响应时间。必须在write/end发送内容之前执行gzip，否则会抛出错误。
     * gzip压缩在1.7.14以上版本可用
     * jpg/png/gif格式的图片已经经过压缩，无需再次压缩
     * @param int $level
     */
    public function gzip($level = 1)
    {
        $this->response->gzip($level);
    }

    /**
     * 启用Http Chunk分段向浏览器发送相应内容。关于Http Chunk可以参考Http协议标准文档
     * $data要发送的数据内容，最大长度不得超过2M
     * 使用write分段发送数据后，end方法将不接受任何参数
     * 调用end方法后会发送一个长度为0的Chunk表示数据传输完毕
     * @param $data
     * @return mixed
     */
    public function write($data)
    {
        return $this->response->write($data);
    }

    /**
     * $filename 要发送的文件名称，文件不存在或没有访问权限sendfile会失败
     * 层无法推断要发送文件的MIME格式因此需要应用代码指定Content-Type
     * 调用sendfile后会自定执行end，中途不得使用Http-Chunk
     * sendfile不支持gzip压缩
     * @param $filename
     * @return mixed
     */
    public function sendFile($filename)
    {
        return $this->response->sendfile($filename);
    }

    /**
     * @param string $html
     * @return mixed
     */
    public function end($html = '')
    {
        if ($this->isEnd) return false;
        $this->isEnd = true;
        if ((is_array($html)
                || (is_object($html) && !method_exists($html, '__toString')))
        ) {
            $html = json_encode($html, JSON_UNESCAPED_UNICODE);
        }
        if (strlen($html) > 0 && Request::isAjax()) {
            $html = json_encode($html, JSON_UNESCAPED_UNICODE);
        }

        $this->response->end($html);
    }

}